import os.path
import time

from module.static_module.parent.model import DynamicModule
from core.constant import *
from conf import conf
from tools.framework import gen_result_folder_name, load_module_from_path, get_ui_value
from module.dynamic_module.fighting.engine import Engine


class FightingModel(DynamicModule):
    def __init__(self, master):
        super().__init__(master, Module.Fighting)
        # 初始视图类变量数据及其实体类变量
        self.fighting_mode_ls = []

        # 实体类映射视图类变量数据
        self.send_email_ls = []
        self.data_name_ls = []
        self.strategy_name_ls = []
        self.research_plan_ls = []
        self.result_folder_ls = []
        # 映射视图类变量数据到实体类
        self.fighting_mode: FightingMode = None
        self.send_email = None
        self.data_name = None
        self.strategy_name = None
        self.research_plan = None
        self.result_folder = None
        # 实体类结构变量
        self.fighting_mode_name = None
        self.equity_data_dc = None
        self.order_data_dc = None
        self.canvas_ls = []  # 记录canvas绘图数据，第一个元素为回测总数量，往后每个元素均为固定长度列表，代表一个可能被绘制的像素点

    def sec_init(self):
        self.engine = Engine(self)

        self.fighting_mode_ls = [mem.value for mem in FightingMode]
        self.send_email_ls = [mem.value for mem in SendEmailSignal]
        self.data_name_ls = []
        self.strategy_name_ls = []
        self.research_plan_ls = []
        self.result_folder_ls = []
        pass

    def get_ui_params(self):
        # 获取ui界面的相关参数
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(
            LabelMember.FightingMode)
        self.fighting_mode = get_ui_value(values, indices, WidgetCategory.Combobox)
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(
            LabelMember.SendEmail)
        self.send_email = get_ui_value(values, indices, WidgetCategory.Combobox)
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(
            LabelMember.DataName)
        self.data_name = get_ui_value(values, indices, WidgetCategory.Combobox)
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(
            LabelMember.StrategyName)
        self.strategy_name = get_ui_value(values, indices, WidgetCategory.Combobox)
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(
            LabelMember.ResearchPlan)
        self.research_plan = get_ui_value(values, indices, WidgetCategory.Combobox)
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(
            LabelMember.ResultFolder)
        self.result_folder = get_ui_value(values, indices, WidgetCategory.Entry)

    def on_fighting_model_change(self):
        values, indices = self.master.main_window_view.dynamic_module_view.auto_layout.get_value(
            LabelMember.FightingMode)
        self.fighting_mode = get_ui_value(values, indices, WidgetCategory.Combobox)

        self.send_email_ls = [SendEmailSignal.Allow.value, SendEmailSignal.Close.value]
        if self.fighting_mode == FightingMode.LiveMessage.value:
            self.fighting_mode_name = FightingMode.LiveMessage

            self.data_name_ls = self.master.file_manager.data_def_group_dc[DataDefGroup.MkLive.value] + \
                                self.master.file_manager.data_def_group_dc[DataDefGroup.MkFtLive.value]
            self.strategy_name_ls = self.master.file_manager.data_def_group_dc[DataDefGroup.DDQMName.value]
            self.research_plan_ls = []
            self.result_folder_ls = [gen_result_folder_name(ResultFolder.FHT_LM)]
            pass
        elif self.fighting_mode == FightingMode.HistoryMessage.value:
            self.fighting_mode_name = FightingMode.HistoryMessage

            self.data_name_ls = self.master.file_manager.data_def_group_dc[DataDefGroup.Mk.value] + \
                                self.master.file_manager.data_def_group_dc[DataDefGroup.MkFt.value]
            self.strategy_name_ls = self.master.file_manager.data_def_group_dc[DataDefGroup.DDQMName.value]
            self.research_plan_ls = []
            self.result_folder_ls = [gen_result_folder_name(ResultFolder.FHT_HM)]
            pass
        elif self.fighting_mode == FightingMode.LiveSimulate.value:
            self.fighting_mode_name = FightingMode.LiveSimulate

            self.data_name_ls = self.master.file_manager.data_def_group_dc[DataDefGroup.MkLive.value] + \
                                self.master.file_manager.data_def_group_dc[DataDefGroup.MkFtLive.value]
            self.strategy_name_ls = self.master.file_manager.data_def_group_dc[DataDefGroup.DDQSName.value]
            self.research_plan_ls = self.master.file_manager.data_def_group_dc[DataDefGroup.FHTSummary.value]
            self.result_folder_ls = [gen_result_folder_name(ResultFolder.FHT_LS)]
            pass
        elif self.fighting_mode == FightingMode.HistorySimulate.value:
            self.fighting_mode_name = FightingMode.HistorySimulate

            self.data_name_ls = self.master.file_manager.data_def_group_dc[DataDefGroup.Mk.value] + \
                                self.master.file_manager.data_def_group_dc[DataDefGroup.MkFt.value]
            self.strategy_name_ls = self.master.file_manager.data_def_group_dc[DataDefGroup.DDQSName.value]
            self.research_plan_ls = self.master.file_manager.data_def_group_dc[DataDefGroup.FHTSummary.value]
            self.result_folder_ls = [gen_result_folder_name(ResultFolder.FHT_HS)]
            pass
        elif self.fighting_mode == FightingMode.LiveReal.value:
            self.fighting_mode_name = FightingMode.LiveReal

            self.data_name_ls = self.master.file_manager.data_def_group_dc[DataDefGroup.MkLive.value] + \
                                self.master.file_manager.data_def_group_dc[DataDefGroup.MkFtLive.value]
            self.strategy_name_ls = self.master.file_manager.data_def_group_dc[DataDefGroup.DDQRName.value]
            self.research_plan_ls = []
            self.result_folder_ls = [gen_result_folder_name(ResultFolder.FHT_LR)]
            pass
        else:
            pass

        pass

    def on_run_thread(self):
        try:
            from core.map_obj import FightingModeServerMap

            # 点击运行按钮回调
            self.get_ui_params()
            # 重新加载数据和交易引擎
            self.engine.add_data_server(FightingModeServerMap[self.fighting_mode_name][0])
            self.engine.add_trade_server(FightingModeServerMap[self.fighting_mode_name][1])
            # 加载策略
            template_path = os.path.join(self.master.file_manager.strategy_path, self.strategy_name)
            template_py = load_module_from_path(template_path)
            strategy_ins = template_py.DDQStrategy()
            # 加载策略对应数组管理器
            factor_am_path = self.master.file_manager.factor_am_path
            factor_am_py = load_module_from_path(factor_am_path)
            factor_am_c = factor_am_py.ArrayManagerFactor
            # 加载策略的关键参数
            strategy_ins.load_key_value(template_py.Symbol, template_py.P, factor_am_c)
            self.engine.add_template(template=strategy_ins)
            # 将template中的参数数据加载至account
            self.engine.trade_server.set_account_init(template_py.P.cash.value, template_py.P.commission.value)

            data_path = self.master.file_manager.describe_all_dc[self.data_name].path
            is_email = True if self.send_email == SendEmailSignal.Allow.value else False
            self.engine.loop(data_path, is_email, self.fighting_mode_name)

        except Exception as e:
            import traceback
            traceback.print_exc()
            info = f"任务运行出错，错误信息{e}"
            self.master.file_manager.log_engine.emit(info, LogName.Running)
            pass
        self.task_end()

    def on_only_report_thread(self):
        from module.logic_module.researcher.fighting_summary import FightingSummary

        self.get_ui_params()
        if self.result_folder.split('-')[0] == "BT":
            result_folder_path = os.path.join(self.master.file_manager.result_path, ResultFolder.BT.value,
                                              self.result_folder)
        else:
            result_folder_path = os.path.join(self.master.file_manager.result_path, ResultFolder.FHT.value,
                                              self.result_folder)
        # 导入回测生成的数据
        self.equity_data_dc = self.master.file_manager.read_dc_csv(
            os.path.join(result_folder_path, f"{DataCategory.Equity.value}.csv"))
        self.order_data_dc = self.master.file_manager.read_dc_csv(
            os.path.join(result_folder_path, f"{DataCategory.Order.value}.csv"))

        # 导入回测分析方法
        # 使用plan分析数据并在结果文件夹生成md文件
        plan_ins = FightingSummary(self)
        plan_method = getattr(plan_ins, self.research_plan, None)
        if plan_method:
            plan_method()  # 具体方法结合界面确定
            self.task_end()
        else:
            info = f"[{self.module.value}]报告方案调用错误。"
            self.master.file_manager.log_engine.emit(info, LogName.Operate)
            self.task_end()
        # result_dir_path = os.path.join(self.master.file_manager.result_path, ResultFolder.BT.value, self.result_folder)
        # # 定义 Markdown 文件的路径
        # md_file_path = get_latest_file(result_dir_path, ".md")
        # # 转为html并打开
        # self.master.file_manager.md2html(md_file_path, True)
        pass

    def on_stop(self):
        self.engine.set_is_end(True)
        info = "已标记停止信号，将在当前或下一行情节点跳出循环。"
        self.master.file_manager.log_engine.emit(info, LogName.Running)


